package cssOrder.plugin;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public class CSSValidation 
{

    public CSSValidation() {
    
    }

	public ArrayList<String> validateCSSOrder( String filename , String CSS ) {
	
		ArrayList<String> errors = new ArrayList<String>();
		String [] selectors = null;
		selectors = CSS.split("\\}");
		int lineNumber = 0;
		for (int i = 0 ; i < selectors.length; i++)
		{	
			String [] propertiesList = selectors[i].split("\\{");
			if(propertiesList.length > 1) {
				
				ArrayList<String> CSSproperties = filterList(propertiesList[1].trim().split(";"));
				ArrayList<String> sortedCSSproperties = new ArrayList<String>(CSSproperties);
				Collections.copy(sortedCSSproperties, CSSproperties);
				Collections.sort(sortedCSSproperties);
				
				int selectorLineNumber = lineNumber + countLineBreaks(propertiesList[0]) + 1;
				if(!CSSproperties.equals(sortedCSSproperties)) {

					
					errors.add("unordered selector on ln " + selectorLineNumber + " : "+propertiesList[0].trim());
				}
                
                String duplicates = checkDuplicates(sortedCSSproperties);
				if(!duplicates.equals("")) {
					
					errors.add("duplicate property '" + duplicates + "' detected on ln " + selectorLineNumber + " : "+propertiesList[0].trim());
					
				}
				
				String verboseCSS = checkVerboseCSS(sortedCSSproperties);
				if(!verboseCSS.equals("")) {
					
					errors.add("shorthand selector '" + verboseCSS + "' not used, optimization needed on ln " + selectorLineNumber + " : "+propertiesList[0].trim());
					
				}
				
			}
			lineNumber = lineNumber + countLineBreaks(selectors[i]);
		}
		
		return errors;
		
	}
    
    private static String checkDuplicates (ArrayList<String> sortedCSSProperties) {
		
		String duplicateProperties = "";
		
		for (int i = 1; i < sortedCSSProperties.size(); i++) {
			
			if (sortedCSSProperties.get(i).equals(sortedCSSProperties.get(i-1))) {
				
				duplicateProperties = sortedCSSProperties.get(i);
				
			}
			
		}
		
		return duplicateProperties;
		
	}
	
	private static String checkVerboseCSS (ArrayList<String> sortedCSSProperties) {
		
		String verboseCSS = "";
		String [] [] verboseProperties = {
				{"margin-top", "margin-right", "margin-bottom", "margin-left"},
				{"padding-top", "padding-right", "padding-bottom", "padding-left"},
				{"background-attachment", "background-position", "background-repeat", "background-image"},
				{"list-style-image", "list-style-position", "list-style-type"}
		};
		
		for (int i = 0; i < verboseProperties.length; i++) {
			
			boolean containsAll = true;
			for (int j = 0; j < verboseProperties[i].length; j++) {
				
				if (!sortedCSSProperties.contains(verboseProperties[i][j])) {
					
					containsAll = false;
					
				}
				
			}
			if(containsAll) {
				
				verboseCSS = verboseProperties[i][0];
				
			}
			
		}
		
		return verboseCSS;
		
	}
	
	private static ArrayList<String> filterList (String []s) {
	    ArrayList<String> cleanList = new ArrayList<String>();
		for (int i = 0 ; i < s.length ; i++) {
	    	if(s[i].indexOf(":") != -1) {
	    		
	    		String [] CSSProperty = s[i].trim().split(":"); 
	    		cleanList.add(CSSProperty[0]);
	    		
	    	}
	    }
		return cleanList;
	}
    
    private static int countLineBreaks (String data) {
		
		String regex = "\n";               
	    Pattern p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);   
	    int newLinesNumber = 0;
	    Matcher m = p.matcher(data);
	    while (m.find()) {
	    	newLinesNumber++;
	    }
		return newLinesNumber;
	}

}
